# -*- coding: utf-8 -*-
# Module to handle selections and groups of selections 
#
# Version 1.0 - 2008-11-30 by Michael (cookie.michael1@googlemail.com)
#
# licensed under GPL V3
# class to manage selection groups and items
# for the game we need 5 groups of saved selected items
# when player mark items he creates a new selector with the marked items
# to save he assigns the selector a number
# the selector have a visual represenation in the bottom left corner:
# they stack themselves when not use to maximize free desktop space
# they expand when activated

import copy
import pygame

class _SelectionRegistry (object):
    "Keep track of all objects which can be selected, primary used to iterate over them all"
    def __init__(self):
        self._reg = []
    def insert (self, obj):
        self._reg.append (obj)
    def getAll (self):
        return self._reg
    def delete (self, obj):
        pass
    def clear (self):
        self._reg = []

# introduce module wide selection registry
SelectionRegistry = _SelectionRegistry ()        

class SelectItem (object):
    "stub class: inherit to use selection on the objects you want"
    def __init__(self):
        self.selMarker = None
        self.selMarked = False
        self.selPos = (0,0)
        # register self in registry
        SelectionRegistry.insert (self)
    def __repr__(self):
        return "Item"
    def setMarker (self, surface, relPos=(0,0)):
        "Set a small gfx for this object which is shown when you select the item"
        self.selMarker = surface
        self.selPos = relPos
    def hasMarker (self): 
        if self.selMarker: return True
        return False
    def getMarker(self):
        return self.selMarker
    def setMarked(self):
        self.selMarked = True
    def isMarked (self):
        return self.selMarked
    def clearMark(self):
        self.selMarked = False
    def drawMarker(self, destSurface):
        "returns a copy of the destSurface with the mark or the destSurface original if no markings apply"
        if self.isMarked() and self.hasMarker():
            s = destSurface.copy()
            s.blit (self.selMarker, self.selPos) 
            return s
        else:
            return destSurface
              
class Selector (object):
    "Container to handle a selektion e.g. to assign to a hotkey"
    def __init__(self):
        self.list = []
        self.shiftMode = False
    def __repr__(self):
        return "<Selector: " + str(self.list) + ">"      
    def addItem (self, item):
        self.list.append(item)
    def markEveryItem (self):
        for i in self.list:
            i.setMarked()
    def reset (self):
        for item in self.list:
            item.clearMark()
        self.list = []
    def setShiftMode(self):
        self.shiftMode = True
    def isShiftMode(self): 
        return self.shiftMode
    def clearShiftMode(self):
        self.shiftMode = False
    def copy(self):
        return copy.copy(self)
      
# pre-definded selectors
# for every key 1 .. 0 there is one Selector Object
# there is a activeSelector representing the currently selected objects
# load and save works by copying the selectors to / from the activeSelector 

# TODO: init routine?
selectors = {pygame.K_1: Selector (), 
             pygame.K_2: Selector (),
             pygame.K_3: Selector (),
             pygame.K_4: Selector (),
             pygame.K_5: Selector (),
             pygame.K_6: Selector (),
             pygame.K_7: Selector (),
             pygame.K_8: Selector (),
             pygame.K_9: Selector (),
             pygame.K_0: Selector ()
             }   

assignMod = pygame.KMOD_META

activeSelector = Selector()   

def saveSelection (key):
    "Call this function only for keys defined in 'selectors'-dict"
    global selectors
    try:
        selectors[key] = activeSelector.copy()
    except KeyError:
        print "Err: Key not defined in selector.selectors, cant memorize selection"
        
def loadSelection (key, clearAll=True):
    "Load a saved selection into activeSelector, defaults clear any currently active selection"
    global activeSelector
    if clearAll:
        for item in SelectionRegistry.getAll():
            item.clearMark()
    
    activeSelector = selectors[key].copy()
    activeSelector.markEveryItem() 
    
    
def handleSelectionEvents (event):
    "handles all events for the selection KEYUP and KEYDOWN events, you can safely pass any events here"
    if event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
    
        if event.key == pygame.K_RSHIFT or event.key == pygame.K_LSHIFT:
            if event.type == pygame.KEYDOWN:
                activeSelector.setShiftMode()
            elif event.type == pygame.KEYUP:
                activeSelector.clearShiftMode()
    
        if event.type == pygame.KEYUP and event.key in selectors:    
            if event.mod & assignMod:
                saveSelection(event.key)
            else:
                loadSelection(event.key)
            
    # end selection or single click
    if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
        if not activeSelector.isShiftMode():    
            activeSelector.reset()
                

    
# Main / Unit Test

# create 10 items and 2 selectors
# randomly add 5 items to each selector
if __name__ == "__main__":
    s1 = Selector()
    s2 = Selector()
    
    for i in range (0,5):
        s1.addItem(SelectItem())
        
    for i in range (0,5):
        s2.addItem(SelectItem())
    
    print s1
    print s2